package gui.productgroup;

import static org.junit.Assert.*;
import gui.common.SizeUnits;
import gui.inventory.ProductContainerData;

import org.junit.Before;
import org.junit.Test;

import persistence.DataPersistor;

import core.ContainerFacade;

public class AddProductGroupControllerTest implements IAddProductGroupView {
	private String _name;
	private String _quantity;
	private SizeUnits _unit;
	private boolean _ok_enabled;
	
	private AddProductGroupController _suController;
	private AddProductGroupController _childController;
	private AddProductGroupController _grandchildController;
	
	@Before
	public void setUp() throws Exception {
		ContainerFacade.clearAllData();
		DataPersistor.instance().init("-serial");
		
		// Make a tree that looks like this:
		// 		SU
		//      Child
		//		Grandchild
		ProductContainerData su = new ProductContainerData(
				ContainerFacade.instance().addStorageUnit("SU"));
		ProductContainerData child = new ProductContainerData(
				ContainerFacade.instance().addProductGroup(
						su.getContainer(), "Child", "0", "count"));
		ProductContainerData grandchild = new ProductContainerData(
				ContainerFacade.instance().addProductGroup(
						child.getContainer(), "Grandchild", "0", "count"));
		
		_ok_enabled = true;
		_name = "";
		_quantity = "";
		_unit = SizeUnits.Count;
		
		_suController = new AddProductGroupController(this,su);
		_childController = new AddProductGroupController(this,child);
		_grandchildController = new AddProductGroupController(this,grandchild);
	}

	@Test
	public void testEnableComponents() {
		
		setValues("Child","0",SizeUnits.Count);
		_ok_enabled = true;
		_suController.enableComponents();
		assertFalse(_ok_enabled);
		
		_ok_enabled = false;
		_childController.enableComponents();
		assertTrue(_ok_enabled);
		
		_ok_enabled = false;
		_grandchildController.enableComponents();
		assertTrue(_ok_enabled);
		
		setValues("Grandchild","0",SizeUnits.Count);
		_ok_enabled = false;
		_suController.enableComponents();
		assertTrue(_ok_enabled);
		
		_ok_enabled = true;
		_childController.enableComponents();
		assertFalse(_ok_enabled);
		
		_ok_enabled = false;
		_grandchildController.enableComponents();
		assertTrue(_ok_enabled);	
		
		setValues("Bubbles","0",SizeUnits.Count);
		_ok_enabled = false;
		_suController.enableComponents();
		assertTrue(_ok_enabled);
		_ok_enabled = false;
		_childController.enableComponents();
		assertTrue(_ok_enabled);
		_ok_enabled = false;
		_grandchildController.enableComponents();
		assertTrue(_ok_enabled);	
		
		setValues("Bubbles","-1",SizeUnits.Count);
		_ok_enabled = true;
		_suController.enableComponents();
		assertFalse(_ok_enabled);
		_ok_enabled = true;
		_childController.enableComponents();
		assertFalse(_ok_enabled);
		_ok_enabled = true;
		_grandchildController.enableComponents();
		assertFalse(_ok_enabled);	
		
		setValues("Bubbles","0.5",SizeUnits.Count);
		_ok_enabled = true;
		_suController.enableComponents();
		assertFalse(_ok_enabled);
		_ok_enabled = true;
		_childController.enableComponents();
		assertFalse(_ok_enabled);
		_ok_enabled = true;
		_grandchildController.enableComponents();
		assertFalse(_ok_enabled);			
		
		setValues("Bubbles","bogus",SizeUnits.Count);
		_ok_enabled = true;
		_suController.enableComponents();
		assertFalse(_ok_enabled);
		_ok_enabled = true;
		_childController.enableComponents();
		assertFalse(_ok_enabled);
		_ok_enabled = true;
		_grandchildController.enableComponents();
		assertFalse(_ok_enabled);	
		
		setValues("Bubbles","0",SizeUnits.FluidOunces);
		_ok_enabled = false;
		_suController.enableComponents();
		assertTrue(_ok_enabled);
		_ok_enabled = false;
		_childController.enableComponents();
		assertTrue(_ok_enabled);
		_ok_enabled = false;
		_grandchildController.enableComponents();
		assertTrue(_ok_enabled);			
	}

	@Test
	public void testValuesChanged() {
		_quantity = "0";
		_unit = SizeUnits.Count;
		_suController.valuesChanged();
		assertFalse(_ok_enabled);
		// only SU follows changed values, so check it.
		setProductGroupName("C");
		assertTrue(_ok_enabled);
		
		setProductGroupName("Ch");
		assertTrue(_ok_enabled);
		
		setProductGroupName("Chi");
		assertTrue(_ok_enabled);	
		
		setProductGroupName("Chil");
		assertTrue(_ok_enabled);	
		
		setProductGroupName("Child");
		assertFalse(_ok_enabled);	
		
		setProductGroupName("Child2");
		assertTrue(_ok_enabled);	
		
		setSupplyValue("");
		assertFalse(_ok_enabled);
		
		setSupplyValue("1");
		assertTrue(_ok_enabled);
		
		setSupplyValue("1."); // float still converts this to an whole number.
		assertTrue(_ok_enabled);
		
		setSupplyValue("1.2");
		assertFalse(_ok_enabled);
		
		setSupplyUnit(SizeUnits.FluidOunces);
		assertTrue(_ok_enabled);
	}

	@Test
	public void testAddProductGroup() {
		setValues("Bubblegum", ".663",SizeUnits.FluidOunces);
		_suController.addProductGroup();
		
		_suController.enableComponents();
		assertFalse(_ok_enabled);
	}
	
	public void setValues(String name, String quantity, SizeUnits unit){
		setProductGroupName(name);
		setSupplyUnit(unit);
		setSupplyValue(quantity);
	}

	@Override
	public void displayInformationMessage(String message) {
		// Not used
		
	}

	@Override
	public void displayWarningMessage(String message) {
		fail(message);
		
	}

	@Override
	public void displayErrorMessage(String message) {
		fail(message);
		
	}

	@Override
	public String getProductGroupName() {
		return _name;
	}

	@Override
	public void setProductGroupName(String value) {
		_name = value;
		
		_suController.valuesChanged();	
		
	}

	@Override
	public void enableProductGroupName(boolean value) {
		// not currently used
		
	}

	@Override
	public String getSupplyValue() {
		return _quantity;
	}

	@Override
	public void setSupplyValue(String value) {
		_quantity = value;
		
		if (_suController != null)
			_suController.valuesChanged();	
		
	}

	@Override
	public void enableSupplyValue(boolean value) {
		// not used
		
	}

	@Override
	public SizeUnits getSupplyUnit() {
		return _unit;
	}

	@Override
	public void setSupplyUnit(SizeUnits value) {
		_unit = value;
		_suController.valuesChanged();
		
	}

	@Override
	public void enableSupplyUnit(boolean value) {
		// not used
		
	}

	@Override
	public void enableOK(boolean value) {
		_ok_enabled = value;
		
	}

}
